{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "226de2b7-1e4d-4df0-845b-376744a2ac37",
   "metadata": {},
   "source": [
    "- https://github.com/langchain-ai/langgraph/blob/main/examples/agent_executor/base.ipynb"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "99109f3b-258f-4fbf-8bde-b6b7b5a4701d",
   "metadata": {},
   "source": [
    "### agent executor"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cba8dfea-ab0d-4084-acbb-638855f344bd",
   "metadata": {},
   "source": [
    "- 即执行工具（`AgentAction`）的能力\n",
    "- 即为 ReAct 即循环执行工具的能力"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "e116ad21-8fa2-4349-9d90-10ef67c04b40",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-05T15:24:37.000120Z",
     "iopub.status.busy": "2024-09-05T15:24:36.999509Z",
     "iopub.status.idle": "2024-09-05T15:24:37.012692Z",
     "shell.execute_reply": "2024-09-05T15:24:37.011201Z",
     "shell.execute_reply.started": "2024-09-05T15:24:37.000069Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from dotenv import load_dotenv\n",
    "load_dotenv()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "ede721ed-0012-40f3-ba23-0f1a7f30a9d1",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-05T15:24:54.739933Z",
     "iopub.status.busy": "2024-09-05T15:24:54.739322Z",
     "iopub.status.idle": "2024-09-05T15:24:56.311102Z",
     "shell.execute_reply": "2024-09-05T15:24:56.309508Z",
     "shell.execute_reply.started": "2024-09-05T15:24:54.739882Z"
    }
   },
   "outputs": [],
   "source": [
    "from langchain import hub\n",
    "from langchain.agents import create_openai_functions_agent\n",
    "from langchain_community.tools.tavily_search import TavilySearchResults\n",
    "from langchain_openai.chat_models import ChatOpenAI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "c4c1666c-2072-4179-879f-03a35bf30c5c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-05T15:25:01.329074Z",
     "iopub.status.busy": "2024-09-05T15:25:01.328706Z",
     "iopub.status.idle": "2024-09-05T15:25:01.334470Z",
     "shell.execute_reply": "2024-09-05T15:25:01.333445Z",
     "shell.execute_reply.started": "2024-09-05T15:25:01.329050Z"
    }
   },
   "outputs": [],
   "source": [
    "tools = [TavilySearchResults(max_results=1)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "8c29ad7e-e802-4fbe-8856-55806555bc7b",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-05T15:25:13.656298Z",
     "iopub.status.busy": "2024-09-05T15:25:13.655990Z",
     "iopub.status.idle": "2024-09-05T15:25:15.003016Z",
     "shell.execute_reply": "2024-09-05T15:25:15.001280Z",
     "shell.execute_reply.started": "2024-09-05T15:25:13.656276Z"
    }
   },
   "outputs": [],
   "source": [
    "# Get the prompt to use - you can modify this!\n",
    "prompt = hub.pull(\"hwchase17/openai-functions-agent\")\n",
    "\n",
    "# Choose the LLM that will drive the agent\n",
    "llm = ChatOpenAI(model=\"gpt-3.5-turbo-1106\", streaming=True)\n",
    "\n",
    "# Construct the OpenAI Functions agent\n",
    "agent_runnable = create_openai_functions_agent(llm, tools, prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "f4a11bce-74d9-4cf7-b808-76cf8be51e6a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-05T15:27:24.510175Z",
     "iopub.status.busy": "2024-09-05T15:27:24.509796Z",
     "iopub.status.idle": "2024-09-05T15:27:24.515592Z",
     "shell.execute_reply": "2024-09-05T15:27:24.514366Z",
     "shell.execute_reply.started": "2024-09-05T15:27:24.510148Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "================================\u001b[1m System Message \u001b[0m================================\n",
      "\n",
      "You are a helpful assistant\n",
      "\n",
      "=============================\u001b[1m Messages Placeholder \u001b[0m=============================\n",
      "\n",
      "\u001b[33;1m\u001b[1;3m{chat_history}\u001b[0m\n",
      "\n",
      "================================\u001b[1m Human Message \u001b[0m=================================\n",
      "\n",
      "\u001b[33;1m\u001b[1;3m{input}\u001b[0m\n",
      "\n",
      "=============================\u001b[1m Messages Placeholder \u001b[0m=============================\n",
      "\n",
      "\u001b[33;1m\u001b[1;3m{agent_scratchpad}\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "prompt.pretty_print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7ed9178a-cf76-4be5-9a6c-21b3d8bb4202",
   "metadata": {},
   "source": [
    "#### agent state"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7c3b456a-c690-4bf6-8cbe-4f18ab64b47e",
   "metadata": {},
   "source": [
    "- `input`: This is the input string representing the main ask from the user,\n",
    "    - passed in as input.\n",
    "- `chat_history`: This is any previous conversation messages,\n",
    "    - also passed in as input.\n",
    "- `intermediate_steps`: This is list of **actions and corresponding observations** that the agent takes over time.\n",
    "    - This is updated each iteration of the agent.\n",
    "- `agent_outcome`: This is the response from the agent, either an `AgentAction or AgentFinish`. The AgentExecutor should finish when this is an AgentFinish, otherwise it should call the requested tools."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "809dd17a-3d3f-433e-9b74-2a324b9a648c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-05T15:27:02.797024Z",
     "iopub.status.busy": "2024-09-05T15:27:02.796716Z",
     "iopub.status.idle": "2024-09-05T15:27:02.805717Z",
     "shell.execute_reply": "2024-09-05T15:27:02.803741Z",
     "shell.execute_reply.started": "2024-09-05T15:27:02.797001Z"
    }
   },
   "outputs": [],
   "source": [
    "import operator\n",
    "from typing import Annotated, TypedDict, Union\n",
    "\n",
    "from langchain_core.agents import AgentAction, AgentFinish\n",
    "from langchain_core.messages import BaseMessage\n",
    "\n",
    "\n",
    "class AgentState(TypedDict):\n",
    "    # The input string\n",
    "    input: str\n",
    "    # The list of previous messages in the conversation\n",
    "    chat_history: list[BaseMessage]\n",
    "    # The outcome of a given call to the agent\n",
    "    # Needs `None` as a valid type, since this is what this will start as\n",
    "    agent_outcome: Union[AgentAction, AgentFinish, None]\n",
    "    # List of actions and corresponding observations\n",
    "    # Here we annotate this with `operator.add` to indicate that operations to\n",
    "    # this state should be ADDED to the existing values (not overwrite it)\n",
    "    intermediate_steps: Annotated[list[tuple[AgentAction, str]], operator.add]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b560e262-e6f1-4dd2-a88d-071c553acc8f",
   "metadata": {},
   "source": [
    "#### nodes、edges、graph"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fde47eac-2c9a-48c0-8777-43b73ebda13e",
   "metadata": {},
   "source": [
    "- a node can be either a function or a runnable:\n",
    "    - input type is `AgentState`\n",
    "    - The agent: responsible for deciding what (if any) actions to take.\n",
    "    - A function to invoke tools: if the agent decides to take an action, this node will then execute that action.\n",
    "- edges\n",
    "    - normal edges\n",
    "    - conditional edges"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "35c81c96-2795-43b9-b4b7-b5c9104bfd3b",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-05T15:34:03.743631Z",
     "iopub.status.busy": "2024-09-05T15:34:03.743011Z",
     "iopub.status.idle": "2024-09-05T15:34:03.879747Z",
     "shell.execute_reply": "2024-09-05T15:34:03.878126Z",
     "shell.execute_reply.started": "2024-09-05T15:34:03.743580Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_3338036/50744384.py:7: LangGraphDeprecationWarning: ToolExecutor is deprecated as of version 0.2.0 and will be removed in 0.3.0. Use langgraph.prebuilt.ToolNode instead.\n",
      "  tool_executor = ToolExecutor(tools)\n"
     ]
    }
   ],
   "source": [
    "from langchain_core.agents import AgentFinish\n",
    "\n",
    "from langgraph.prebuilt.tool_executor import ToolExecutor\n",
    "\n",
    "# This a helper class we have that is useful for running tools\n",
    "# It takes in an agent action and calls that tool and returns the result\n",
    "tool_executor = ToolExecutor(tools)\n",
    "\n",
    "\n",
    "# Define the agent\n",
    "def run_agent(state):\n",
    "    agent_outcome = agent_runnable.invoke(state)\n",
    "    return {\"agent_outcome\": agent_outcome}\n",
    "\n",
    "\n",
    "# Define the function to execute tools\n",
    "def execute_tools(state):\n",
    "    # Get the most recent agent_outcome - this is the key added in the `agent` above\n",
    "    agent_action = state[\"agent_outcome\"]\n",
    "    output = tool_executor.invoke(agent_action)\n",
    "    return {\"intermediate_steps\": [(agent_action, str(output))]}\n",
    "\n",
    "\n",
    "# Define logic that will be used to determine which conditional edge to go down\n",
    "def should_continue(state):\n",
    "    # If the agent outcome is an AgentFinish, then we return `exit` string\n",
    "    # This will be used when setting up the graph to define the flow\n",
    "    if isinstance(state[\"agent_outcome\"], AgentFinish):\n",
    "        return \"end\"\n",
    "    # Otherwise, an AgentAction is returned\n",
    "    # Here we return `continue` string\n",
    "    # This will be used when setting up the graph to define the flow\n",
    "    else:\n",
    "        return \"continue\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "61cfc4ec-9f44-473b-8a00-25ee061bb2c6",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-05T15:34:49.024880Z",
     "iopub.status.busy": "2024-09-05T15:34:49.024582Z",
     "iopub.status.idle": "2024-09-05T15:34:49.033521Z",
     "shell.execute_reply": "2024-09-05T15:34:49.032670Z",
     "shell.execute_reply.started": "2024-09-05T15:34:49.024857Z"
    }
   },
   "outputs": [],
   "source": [
    "from langgraph.graph import END, StateGraph, START\n",
    "\n",
    "# Define a new graph\n",
    "workflow = StateGraph(AgentState)\n",
    "\n",
    "# Define the two nodes we will cycle between\n",
    "workflow.add_node(\"agent\", run_agent)\n",
    "workflow.add_node(\"action\", execute_tools)\n",
    "\n",
    "# Set the entrypoint as `agent`\n",
    "# This means that this node is the first one called\n",
    "workflow.add_edge(START, \"agent\")\n",
    "\n",
    "# We now add a conditional edge\n",
    "workflow.add_conditional_edges(\n",
    "    # First, we define the start node. We use `agent`.\n",
    "    # This means these are the edges taken after the `agent` node is called.\n",
    "    \"agent\",\n",
    "    # Next, we pass in the function that will determine which node is called next.\n",
    "    should_continue,\n",
    "    # Finally we pass in a mapping.\n",
    "    # The keys are strings, and the values are other nodes.\n",
    "    # END is a special node marking that the graph should finish.\n",
    "    # What will happen is we will call `should_continue`, and then the output of that\n",
    "    # will be matched against the keys in this mapping.\n",
    "    # Based on which one it matches, that node will then be called.\n",
    "    {\n",
    "        # If `tools`, then we call the tool node.\n",
    "        \"continue\": \"action\",\n",
    "        # Otherwise we finish.\n",
    "        \"end\": END,\n",
    "    },\n",
    ")\n",
    "\n",
    "# We now add a normal edge from `tools` to `agent`.\n",
    "# This means that after `tools` is called, `agent` node is called next.\n",
    "workflow.add_edge(\"action\", \"agent\")\n",
    "\n",
    "# Finally, we compile it!\n",
    "# This compiles it into a LangChain Runnable,\n",
    "# meaning you can use it as you would any other runnable\n",
    "app = workflow.compile()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "d85c9d09-4ea0-49ac-b8ca-72c32b803450",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-05T15:35:13.079526Z",
     "iopub.status.busy": "2024-09-05T15:35:13.079170Z",
     "iopub.status.idle": "2024-09-05T15:35:15.402198Z",
     "shell.execute_reply": "2024-09-05T15:35:15.400232Z",
     "shell.execute_reply.started": "2024-09-05T15:35:13.079499Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCADuAPMDASIAAhEBAxEB/8QAHQABAAICAwEBAAAAAAAAAAAAAAYIBQcBAwQCCf/EAFMQAAEDBAADAgcJDAUJCQAAAAEAAgMEBQYRBxIhEzEIFBUWIkHRMlFTVVaSk5TTFyM1NlRhcXWBlbPUCUJ2kaEkNENSYnKCtMEYJTNEV2ODhbH/xAAaAQEBAAMBAQAAAAAAAAAAAAAAAQIDBAUG/8QAMhEBAAECAQkGBgIDAAAAAAAAAAECEQMEEiExUVJhodEFExRBkcEjMnGBsfAVM0JT4f/aAAwDAQACEQMRAD8A/VNERAREQEREBERARdFbWQW6kmqqmRsNPC0vfI7uaB3lR1lqrcuaKi6S1dutjxuK1RPMMj2+p072nm3/AO21wAB07m7htoovGdVNo/dS2ZyrvVvt7+Sqr6amf/qzTNYf8SvP51WT44oPrTPaumjwfHbfHyU1htsLfXyUkYJ9fU66nfXZXf5rWX4ooPqzPYs/g8eRocedVk+OKD60z2p51WT44oPrTPaufNay/FFB9WZ7E81rL8UUH1ZnsT4PHkuhx51WT44oPrTPannVZPjig+tM9q581rL8UUH1ZnsTzWsvxRQfVmexPg8eRocedVk+OKD60z2rluU2ZxAbd6Ak9wFSz2p5rWX4ooPqzPYuDitkcCDZ6Ag9CDSs9ifB48jQyUcrJmB8b2vY7uc07BX2o3JgVrgkM9pY6wVmwe2toETXa6afHrkeNdPSaT7xBAK9dkvFRNUy225xshusDA8uiBENTGToSxbJIG+jmEksPQkgse/GaKZjOom/5S2xmURFpQREQEREBERAREQEREBERAREQEREBERBGMm1c8jx+yv06CR0txnYd+myAs5R9LLE7/gUnUZu7fFc9x2rcD2U9LV0GwNjtHdlK3Z9XowSKTLoxPkoiNnvKzqgRa/PhCcLGkg8SsPBHQg36l+0X1J4QPC6GRzH8ScQY9pLXNdfaUEEd4I7Rc6PNZ+OFuyLPrljFqx/Ibiy21r7bWXuCjYbfBVMiEroXPMgeCAWjfJy8zgObqFGOB/Hm98RMbym53vDb1QC01txZG+Cnhc2aOCd7G07GMnke+oDW6cNcpcDykjSwE2LZLfOOVmyvDsX83bZUV7Ki6ZVRXyGa3ZBbOwPKXUrHEulO2ckhb6IG+cggDz27BuJ9lwLilgtotLrVVXCru9yseVwXKFscpqagzRxcgPaxSake3nLdNLQQT0QTy1eEdZqyHJ23PHckxm5WC0SX2a1XmjjiqaijYHblh5ZHMd1YW6LgQSAdKI5/wCFHcaXhVTZfi2EZA6lrK61xUlVc6WnZHUwVUzWufGw1Afvl9BpcAOeWI9WEuEDoOBeRw3zJ6+x8LWYdbrtgNzx0Uxu1NPVS17+R8ck7g8hwfosD+dztjb+UFbW4h8NMjvvg02TG7ZRRSZNaqez1LbfNO1jZZaOWnlfD2my0E9k5odvl2R111Qbcx67TX2y0lfUWutss07eZ1Bcez7eHqRp/ZvezfTfouPesiteU/G/GrRRU0ecXWzcPr/KwySWK93yjFREzmcGOJbIWkODdggn3vUvv/tC8K//AFLw/wDf1L9og2AoxnerfSUF7Zps9sq4nF3vwyPbHM38/oOLtHpzMb3a2Pdi+Z4/nFBJXY5fbbkFFHKYX1Nrq46mNsgAJYXMJAdpzTrv0R768PEceMYtLQt2Za+eCjYAN9XytBP6A3mcfzNK6Mn/ALaY48vPkyp1pOiIudiIiICIiAiIgIiICIiAiIgIiICIiAiIgxt/srL9bXUzpDBK17JoJ2jbopWODmPHv6IGx6xsHoSvNZsjFTUC23ER0N7Y3b6Xm6Sgd8kJPu2fn7xvTtFZteG72Sgv1L4vcKWOqiB5miQdWu9TmnvafzjRW6mqLZler8Lfyl2+TaT8lh+jHsTybSfksH0Y9iwAwRsILaW/X2lj1oMFcZeX9BlDz/iuPMif5U376eL7JZZmHv8AKS0bUoa0MaGtAa0DQA7guVFvMif5U376eL7JPMif5U376eL7JO7w9/lK2jalKKvvg5XnIOKlizCsvWT3Vstqym42en8VfGwGCBzQzm2w7d1Oz/gts+ZE/wAqb99PF9knd4e/yktG1I5aOnndzSQRyO7tvYCV8eTKP8kg+jHsUf8AMif5U376eL7JcjCJvXlF+cPe7eIf/kad3h7/ACktG1nampobJRyTzyQUNKzq+R5EbB6up7veCw1uglyO7U95qoH09FSh3k6nnY5kvM4Frp5GnRaS0lrWkbDXO5uruVnbQYRa6KrjrJWz3KtjIdHU3GofUOjOtbYHkhh1vq0DvPvlZ9SaqKItRpmfP9/eCaI1CIi0IIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgrv4FH4p8SP7fXn+IxWIVd/Ao/FPiR/b68/xGKxCAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiCu/gUfinxI/t9ef4jFYhV38Cj8U+JH9vrz/EYrEICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAi8V5u9PYrdLW1POY2crQ2NvM97nENa1o9ZLiAB75UXdkGWTHnitdop2HqI5q2R7wP9otj1v8w2Pzlb8PBrxIvGrjNlsmqqP/SS8FJuJfBeDJrdG+a64e+Ws7Jp3z0kgaKjp77ezjfv1Njd76sD5czD8hsf1qb7NdVVcsqrqWamqLZYJ6eZhjkikqJi17SNEEdn1BB0tvha9sesFn5IeBfwN+7rxxtFuq6ftcetZFzupc3bHwxuGoj6vvjy1mu/lLiO5ftWq1+DtwDq/But2Q0tgprTVuvFe6qfUVNRL2jIRsQwbEfpNYC7qepL3H16G3fLmYfkNj+tTfZp4WvbHrBZN0UI8uZh+Q2P61N9mspY8oqai4ttt2pIqKukY6SB9PKZYZ2tI5gHFrS142DykdQdtLuV3LjVk9dMX0T9JgskaIi5UEREBERAREQEREBERAREQEREBERAREQEREBERBEeJR/7stI9Ru1Hsf8Aygr1rycSvwZaP1tSfxAsXxAyCmxXB79d6u7R2KCjopZTc5Ye2bTENOpOz/r6OjyDq7u9a9Kj+mn6z7L5M+iqfZeOXEHFJ81pbjHecgNJh8+S2o5FaKagqXSRPDC3s6Zx3EedrtPDZBykfnXTFxxybCbhebrJnMXEqzW/BpcheylpaaGGGtdLE2KN7oWbDHDnLQXcwAeTzdCMM+EW2RVxwLKeMDMitM11o75X2Otp533Ka70FrpYKF3YufFJTGmqHyObzhreWQPOnb5theHh5xEz+Gw8FspvuVi+UuaTxW+vtZt0EEcTpKSWWOaN7Gh4eHQ+ltxaeY8rWDQFzhZpkjJC4Nc1xaeVwB3o+8f7wsPdTrLsO166+YH9HidQf+gWmvBVx67W+XiBVVmU191pW5Zd6Y0NRT0zI3TNqBuoLo4mv53aO2h3IOY6aOmtyXb8bsM/WE3/J1C3YU3vPCr8SsJ8iIvJQREQEREBERAREQEREBERAREQEREBERAREQEREER4lfgy0frak/iBeDNcPtmf4pdccvMTprZcoHU87GPLHcp9bXDuIOiD74CkOY2eS82XkgfGypppoquEynlYXRvD+Vx0dBwBbvR1vejpa6wrjdjXEOzG6Y/5Ru1G2V0EktDQS1LGSN1zML4muYSNjucQd7BI6r08GO8wopp0zEz7MtcaEcn4AQ2qW53+DI8qyHKJLHV2Zk9ddo4pJ4ZACyMPbEGwua9oc2RjQ4OJLufuUE4LcI8wttzqrJeLLXWvh3W22opbpZ7/VWyp8akeGtZ2PiMMZa0N7QOLzshw6Aja37550/wAVX79yVf2aeedP8VX79yVf2az8PXuyZs7EYwXgnTYHJyQ5ZlV2t8dI+hpbbdbi2anpYna0GNDGlxaGgNdIXkDoD1K+6DgfYrdjGAWKOruLqTCqqGrt73yR9pK+OGSFomPJpw5ZXE8ob1A7u45KycV7Bk0NTLZ/KN1ipah9JO+htlRM2KZnu4nFrDyvbsbaeo31WS886f4qv37kq/s1e4r3ZM2djDYrwmoMMzK93613e7xQXiokrKmyPqGOoBUycvaTtYWc4e7l2fT5dk9Fnbt+N2GfrCb/AJOoXX550/xVfv3JV/ZqPXfiVYLPxFwqhyCokx91xqJo7SLjA+N1bVcnZ9mNj736Mp0XlvMXANB6qxTOFEzVFotPOJgiJjW3GiIvHYiIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAsFnOZW/h7iN1yS6tqXW62wGeZtHTunlLR6msaCSeo/MO8kAEjCcTOIN1wqkszrDiNxzSquNzjt7oba9jW0rSSZJZXuOmNa1ru/pzaaS3e12YrwzZjWe5VlUl/vN2qb6Ymtoq2qLqWhhjb6McMQ0B6Tnu2evpa98uDHW6iyPO8mw/MqbILljeKi2maoxGqtzIqmeokadeMvdtzeQO9w3+s3fMVPLdbaS0UcdJQ0sNFSx75IKeMRsbsknTQABskn9q9KIC0x4XPG5vAbgjer7BMI73VDyfaR0341I06fo/6jQ5/Xv5NetbnWnfCH8FvFfCXjsMeUXG9UUdmM7oGWmoiiEhl7PmLw+N+yOzGta1zO799Aob/Rq8eX4TxXq8Ju9WfJWWEGB8z+kde0EsOyf9I3bD6y4Rhfqovzo8GbwE8F4hUWSXuqvuUW25Y/lldbKGa21kEZYymkZ2Uh5oHffNnZI0NgaAX6LoC6aijp6zsu3gjn7J4lj7RgdyPHc4b7iN967kQapqrXknBu153k1LXZHxNZWVLa+hxhxiM1JzP++x079Almncwj9Qj00FziTsHH8hgv8AbLdVdjPb6ispI6zydXNEdVCx4B1JHs8rgToj1EELKqI3bhVjN54h2bOqm3E5TaaeSlpa+Od7D2Lw4GN7QeV7fTcQHA6J2EEuRantvFK6cMcPdcONlfjuOSyXfydR3C2zSmlqWPG4XOD27iOg8HZ0AwuJA7trMe2VjXscHscNtc07BHvhB9IiICIiAiIgIiICIiAuvxiL4RnzguxajznN7Tw7xqpvl6mfFRwFjAyGMySyyPcGsjjYOrnucQAB76DbHjEXwjPnBPGIvhGfOCr8/jjb7di9zvl9xzI8ZhonwxMprpQtE9ZJK7lijgbG94ke52hy7BBI3peCbwjsfttlyKtvNovthrLDDBVVlpuNIxtX2E0nZsmja2RzZGc2weVxILSCN6BCyHjEXwjPnBPGIvhGfOCrseOcE8eRUceNX233+2Wl13gtlzpoo5KyDZaJI9S60HAAte5jhsbAUMl483qt8G6izKutN9xy41NPRdpcqOhpKlrTK1jjUxQvqNGAk8oDyHjnHo9DoLb1dypKCmlqKmqhp6eJpfJLJIGta0d5JPcFDKrKMnuefWOks9pttTgNVb31VdkElx5ZudwIiigiaN79y4uJ1yuOiCADqvKPCEs+L3nKLe7H8iuYxjs33ert9HG+ClifAyYSlzpGlzQxx2GgvHI48utEyqx8RrTkWXV+PUInlqKS3Ut0NTyt7CSGoMgj5DvZP3pxO2jvHU+oJrwx4a4zwhxnyFjcT6eidUSVcr6mpfPNPM87fI97yS5x0P7lLfGIvhGfOCrjR+ETY7vjuN3K0WW/Xusv1K+upbPQUsb6xlO13I6WXcgjY0OIGy/qTobO9TTBs5tvEKwi62wVETGzSU09NWRGKemnjcWyRSMPVr2kaI/aCQQUG3kREBERBXbwKPxS4kf2+vP8RisSq7eBR+KXEj+315/iMViUBERAREQeG92K25LbJ7bd7fS3S3zgCWlrIWyxP0djbXAg6IB/YoXV41k2O8Qb/mMeTXG8Y3JaSGYYymjdy1MQBa6nkOiC8B4LT3ueCXaADdhL5k9w79BQRThrxDg4jYZbb+61XHHZKsOa+2XqA09VC9ri1zXMP52nR9Y0VKfGIvhGfOC1LnGcW7ALMy4XFtROZp2UtLR0URlqKqd++SKJg9046J9QABJIAJUKqvCNx+1WK+193tF+slXZTSGstNbRt8cbFUzCGKVjWPc2RheTssc4+g4a3oELH+MRfCM+cE8Yi+EZ84LQVo432Srqb/T3ihueJVNloBdamK+wsjJozzjt2GN7wW7Y4EbDgRogFQ+2cdLjmPFzALXb7RfsfsN1pLjUyi9W+OFtwYyOJ0L4ztz2gbcdHkOnt2NEILXte1421wcPzHa+lhsY/wA0l/3/APoFmUBERAREQFX3jlhN2zTFLa+wtgmvVku9He6SkqpOziqn08gf2Ln6PLzDYB10Ov0qwSx/kGh+BPz3e1BWXNrfnPFPFYJ34WMcu2P3e33u3UNfdIJvKEkEhdJE50Rc2MFvRriTskbDdbUP4jcNM84rxZtkM+MeQq2psdLY7ZZJa+CWecNrG1Es0j2v7No6aaOcnQcTokBXK8g0PwJ+e72p5BofgT893tQaByPA7teuNTruyAMssuH1lndWl7fQqJKmJzW8m+Y+i1x3rXTW9lQF+E53efBdqeH1XiTqG92qgoLbSvFwp5Irh2MkYdJGQ8cg5Yg7UnKfS1roreeQaH4E/Pd7U8g0PwJ+efagrVX8PMgnrOPL2W/mZk9JFFaT20f+UuFsEBHuvQ++Dl9Pl9/u6rF41iea8OcpoLtQ4v5ebX4nbLRURsuEMHiNXTdpvtS53pRntfdR85HKdNOwt34tlVhq+IN64ePZdai/2Khpq2atuELWMrIpuYCSN0Ya06LeU6a0b2ADp2p15BofgT893tQUUsHg837H7Vw+u174e27OpKDHTY7njlZPTGWkkFQ+aOeF8juyd/4jmuHMDojW+oVk+GWPUuN4hS09NitDhjpXOnms9udG6OF5OurmNDXOLQ3ZA7+mzra2x5BofgT893tTyDQ/An57vagyCIiAtJeEZxnumIeS8EwWKO5cT8o3DbKY9WUMPUSVs3fysYA4jY6kHoQ1wUq458ZrXwQwiS9VkMlxuVRI2jtNnp+s9xq39I4WAbPU95AOgD0J0DFfB04MXPEDdc7zqWO48T8o1Nc6hvpMoIehjooe/TGANB0epaOpDWlBLuBvCGi4JcPaTHKWrnudW6R9ZcbnUuJkrayQ7lmdsnWz3D1ADZJ2TP0RAREQEREBfMnuHfoK+lwRsEHuQVq8IvhlW8R8dsEtvtlDf6mxXeK6Oslyc1sFxiDHxyQlzgWtcWyEtc4aBA2oTeuEs964VZJS2DhPbsEvNXWW4RUlLPSdtUwxVkE0jpHREMaGhryG85J175AVvPIND8Cfnu9qeQaH4E/Pd7UFWeM3Bm+cTMvyttKxlLb7phXkiCvkkbyCsFWZmsc0Hn5dcuzy60T3nou610ufZnxX4e3y/YMcZpLFSXGGtm8p01QwyzRxNb2bWOLuQmM6JG+vUDvO7uFdkmkx+sN2ymhzSo8oVAZX29jI2RR8/owERkjmjHoknqfWpl5BofgT893tQebGP80l/wB//oFmV0UtHDRMLYW8jSdkbJXegIiICIiAiIgIiICIiCGcTqTNqi32h+CVdspa+K6U0lfHdGEsqKIO+/RtcASxxB2HAE9CBonaxt48IjhvY81s+I1OYW6TJbtUClpbbRvNTL2h5S1snZBwh5g9pBkLQ7Z1vR1BPDPoeMNdwxLOElRDE8NmF3ggYDcZ4HM5QymLgQDpzyeXUmwzkcCCHflf4NrZrV4SnDaKeJ9PPHk9BDJFI0tcxxqGNIIPceukH7oIiICwuaZlZ+HuK3PI7/Wx26z26Ez1FRJ3NaPUB3lxOgGjqSQB1Ky8srIInySPbHGwFznvOg0DvJPqCqtb45PDR4ksudQx33EMUrT4lA8EMyW4RnRmcP61PGdgDuce/e3BgZbgdhd441Z1Hxwz2jkpI+zdHhmO1HdbKN3/AJqRvd28o0d+oEf7IZZZcAAAADQHqC5QEREBERAREQEREBR3LuI+JcP/ABTzoyiy4343z+LeV7hDS9tycvPydo4c3LzN3ru5h74UiVUf6RnghJxT4J+cFvifNe8RdJXRsafd0rg0VLde+Axkm/eiIHegk3ArjnwIsuK19NjWX2bHaOS7Vcr6O+XmCKeSd0m3yta+UkxvPVpHQjuViF+P/wDR78DPuucb6e73CnEuPYsGXGpD27ZLPs+LxH/iBeQehETge9fsAgIiICIiAiIgIiICIiAondshudbdKq32R9JTiic2OprKuJ0wEha1/ZsY17TsMc0lxOhzNADuupYoDjxJu+U7O9XZ2voYV2ZPTE51Uxe0e8LD75sx+PrT+55P5hamz/wYKHiLxEx7Oa+rttFlNlrqevjuFutb4nVLoXtexs47ciQba0b0HaGg4BbxRdWfwj0jot2H5sx+PrT+55P5hObMfj60/ueT+YXqkvlvivUFofWwNuk8D6qOjMg7V8THNa6QN7+UF7QT3bcF57flVruuQXeyUtSZbnaWwurIOye3shK0uj9IgNdsNPuSda66TP4R6R0LojxS4d5NxYwquxe4ZjHa7bXgMqn2q2mKWaLfpRFxmdpju52tEjpvRIOaxrHb9h9gt9ks1yslutVBC2npqWGzSBsbGjQA/wAp/wAT1J6nqpUiZ/CPSOhd5rTkNyorpS2+9vpKgVrnR01ZSROhBkDXP7N7HPcdljXEOB0eUghvTcsUByEkXfFtHW7s3f0Myny5copiM2qItePdJERFxoIiICxmQ5Hb8Wtrq65VAggDgxo1t0jz3Na0dXOOj0HvE9wKyarXlGUyZvfpro6QvoWOdHb49+iyHu59f6z9cxPvFo9S9Ts/IpyzEmJm1Ma+n3XilV2433urkPke2Ulvg/qvuXNNIf0sjc0N/Y9yxh4t5nvpVWgf/XyfbKLIvtKez8loi0Ycfn8sc6Uo+61mf5XZ/wB3SfbL5m4q5hURPilqLNJG9pa5j7a8hwPQgjtuoUZRZ+Byb/XHoZ0sPwYs9TwEx2tsuJm2wUdZWyV0rqiifJIXu0A3m7Uei1oDWj1AdSSSTsD7rWZ/ldn/AHdJ9sousdW5Fb7fe7baKio7O4XJsr6WHkce0EQaZOoGhoOb3kb302pOR5LGvDj0hc6U5+61mf5XZ/3dJ9su+m4x5dTvDpm2esjHfGKaWFx/4+0cB80qIIk5Dks6Jw49EzpbywvilbstqG0M0L7XdSCW0szg5swA2TE8e60OuiA7oTrQ2poqryR84aQ98cjHB7JY3cr43A7Dmn1EHqCt+8M8tkzDF46ipLTcaaQ0lZyjQMrQDzAeoOa5r9erm0vlu0+zqcmiMXC+XZs/4y1pWiIvnkEREBERAUAx78L5V+tnfwYVP1AMe/C+VfrZ38GFd2Taq/p7wsapaE8IW6Xe/wCTZHR4jV5LFdcYsba6tnoshNrt9EXCV8TjG2N5qZXCNxLHDk5WNG2klfViv1644ZritiuuR3XH7b5jUGSTQ2GrdQz19VUuLXuMrNPEcfL7lpA5njexoLb2W8FcLzq/C83yxsrq8wtppXdvLHHURNJLY542PDJmgk6EjXAbK8d28H/Ar1ZrDa6qxONNYYfF7ZJDW1EVRSxa12bZ2SCTk0AOUuI0ANdFc2bo1pduG1I7wosLpKi+5HMabEKp4qTeqiKWZ0NXSgc5jc0ODg4l7dafoFwOgo7nWW5Fh2T8X7da8iulPDU3rHaKGsq6x9QLRHXP5aiSASEtiA5zygABp5dDoFvO8cCcHv1ssFBV2QiCwsdHbXU9ZPBLTscAHNEkb2vLXaGwSQdDe1lLhwuxa7S5PJXWeGsOSxQw3ZlQ572VTYmlkYLSdN5QehaAd6PeAUzZFbOMl4v3Bt3EDGrHl2QV1I7B5L9DPcrlJU1dvqo6pkIdHO487WyNefRJ1uM60NhbOxyluOB+EBaLBHkV6vNqveN1VdUw3iudU8tVBPA0Sx83SLmbM8FjA1ndpo0pTQ+D1w/t2PX6yRWEvob7C2nuTqitqJp6iJvuWGd8hlDR10A4AbOlLZsQtFRlNDkclJzXmipJaGnqe0eOSGRzHPZy75TsxsOyCRroRspFMjryH8L4r+tm/wAGZT9QDIfwviv62b/BmU/Uyn5aPp7ys6oERFwoIiIMXlUksWMXh8G+3bRzGPXfzch1/iqyWwNbbaQM9wImAdNdNBWuc0PaWuALSNEH1qsd2x2XDrxU2SUEMpzule7/AEtOT97cD6yB6J/O0+ohfWdhYlMd5hzr0STqeZFhMip8knfB5BuFromAHtRcaGSpLj01y8k0evX37/YsR5P4ha/D2M7/AFJUfza+omuYm2bM+nVgwvHXIrxZ7Rj1vs0hp573d4bdJUCp8WLWOY93K2Xkf2bnlgaHBpI2dddEQbJqDPcKwPJpqq6T2+ifLbhQubepLhV00prI2ykTSRMPI5rgOV3MO/1OIW1n4hccottba82fZb7a52t5aejoJaYtcDvmLnTvOx00W6IPrXNLwmxWjsNZZo7a91BWTRT1DZauaR8r43NdGTI55f0LG9N66a7lxYmDiYtVVUTa8aNOrRbyifrrVrHM8ku/CK65nT2u53G6QxYw27QMutS+qMFT27oi9pfshuiHFnd6PQBe2nw/zW4vcOJHZBdsgkqqK5OknuVYZ2OcIoSXxg9GB3N3N6aA6LbFZiNnuF4qLpU0LKisqKE22V0hc5slMXFxjLCeUgknrrfXW9KNWzgzjeLTxXDHLfHQXikikioairnqKmKAPABb2ZlHodB6II16tKTk9edeNMXiY06rTfmJ4ihht/EP1X7Gf3JUfza7aWhzxtVCam945JTh4MjIrPUMe5u+oa41RAOu4kH9BXZnzuzy6oly2TwEc/xrJ29ey7SncOnTnLHA/wCAYtZzTMgidJI7lY0bJW9OE2LT4xi3NWRmK4XCU1lRG7vjJa1rGH87WNaD/tcy8rtjEpoyWaJ11Wt9puzjzTVERfBAiIgIiIChlztVxsV3rq230D7tR18jZpaeCRjJoZQxrCW9o5rXMLWA62CCD7rm9GZotuHiThTeNN1ibID5bvPyLvf01D/Mp5bvPyLvf01D/MqfIunxUbkc+q3jYgPlu8/Iu9/TUP8AMp5bvPyLvf01D/MqfInio3I59S8bEB8t3n5F3v6ah/mU8t3n5F3v6ah/mVPkTxUbkc+peNiGWy1XG+3ahrbhQPtNHQSGeKnnkY+aaUscwF3Zuc1rAHk62SSR7nl9KZoi5sTEnFm86LJM3ERFqQREQFgsuw635lb209a1zJYnc8FTEdSQu1rYPrB9YOwf7lnUWdFdWHVFdE2mBoK7cJ8rtLyKanp77CPcyU0rYJT+mOQho/Y8/sWMOEZeCR5p15/RU0n26sgi96ntzKaYtNNM/afaYXRsVu8ycv8AklX/AFmk+3TzJy/5JV/1mk+3VkUWf87lG5Tz6mjYrd5k5f8AJKv+s0n26eZOX/JKv+s0n26siifzuUblPPqaNit3mTl/ySr/AKzSfbrvpuHmY1cgYMdfSb/0lZWQNYP09m97v7gVYpFJ7dyif8KefU0bGucI4Rx2OshuV5qI7jcInc8MMTSIIHe+N9XuHqcda9QB6rYyIvEx8oxMprz8WbygiIucf//Z",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from IPython.display import Image, display\n",
    "\n",
    "try:\n",
    "    display(Image(app.get_graph().draw_mermaid_png()))\n",
    "except Exception:\n",
    "    # This requires some extra dependencies and is optional\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "7c87ec15-1347-4aec-b205-7d481d054ec2",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-05T15:41:15.732174Z",
     "iopub.status.busy": "2024-09-05T15:41:15.730873Z",
     "iopub.status.idle": "2024-09-05T15:41:23.575266Z",
     "shell.execute_reply": "2024-09-05T15:41:23.573817Z",
     "shell.execute_reply.started": "2024-09-05T15:41:15.732108Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'agent_outcome': AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"weather in San Francisco\"}', 'name': 'tavily_search_results_json'}}, response_metadata={'finish_reason': 'function_call', 'model_name': 'gpt-3.5-turbo-1106', 'system_fingerprint': 'fp_1867888df6'}, id='run-71137537-41db-4f1b-ab05-11d20d542542-0')])}\n",
      "----\n",
      "{'intermediate_steps': [(AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"weather in San Francisco\"}', 'name': 'tavily_search_results_json'}}, response_metadata={'finish_reason': 'function_call', 'model_name': 'gpt-3.5-turbo-1106', 'system_fingerprint': 'fp_1867888df6'}, id='run-71137537-41db-4f1b-ab05-11d20d542542-0')]), '[{\\'url\\': \\'https://www.weatherapi.com/\\', \\'content\\': \"{\\'location\\': {\\'name\\': \\'San Francisco\\', \\'region\\': \\'California\\', \\'country\\': \\'United States of America\\', \\'lat\\': 37.78, \\'lon\\': -122.42, \\'tz_id\\': \\'America/Los_Angeles\\', \\'localtime_epoch\\': 1725550871, \\'localtime\\': \\'2024-09-05 08:41\\'}, \\'current\\': {\\'last_updated_epoch\\': 1725550200, \\'last_updated\\': \\'2024-09-05 08:30\\', \\'temp_c\\': 15.2, \\'temp_f\\': 59.4, \\'is_day\\': 1, \\'condition\\': {\\'text\\': \\'Partly cloudy\\', \\'icon\\': \\'//cdn.weatherapi.com/weather/64x64/day/116.png\\', \\'code\\': 1003}, \\'wind_mph\\': 3.8, \\'wind_kph\\': 6.1, \\'wind_degree\\': 20, \\'wind_dir\\': \\'NNE\\', \\'pressure_mb\\': 1018.0, \\'pressure_in\\': 30.05, \\'precip_mm\\': 0.0, \\'precip_in\\': 0.0, \\'humidity\\': 100, \\'cloud\\': 25, \\'feelslike_c\\': 15.2, \\'feelslike_f\\': 59.4, \\'windchill_c\\': 16.5, \\'windchill_f\\': 61.7, \\'heatindex_c\\': 16.5, \\'heatindex_f\\': 61.7, \\'dewpoint_c\\': 12.9, \\'dewpoint_f\\': 55.3, \\'vis_km\\': 16.0, \\'vis_miles\\': 9.0, \\'uv\\': 5.0, \\'gust_mph\\': 4.2, \\'gust_kph\\': 6.7}}\"}]')]}\n",
      "----\n",
      "{'agent_outcome': AgentFinish(return_values={'output': 'The current weather in San Francisco is partly cloudy with a temperature of 15.2°C (59.4°F). The wind is coming from the north-northeast at a speed of 6.1 kph. The humidity is at 100%, and the visibility is 16.0 km (9.0 miles).'}, log='The current weather in San Francisco is partly cloudy with a temperature of 15.2°C (59.4°F). The wind is coming from the north-northeast at a speed of 6.1 kph. The humidity is at 100%, and the visibility is 16.0 km (9.0 miles).')}\n",
      "----\n"
     ]
    }
   ],
   "source": [
    "inputs = {\"input\": \"what is the weather in sf\", \"chat_history\": []}\n",
    "for s in app.stream(inputs):\n",
    "    print(list(s.values())[0])\n",
    "    print(\"----\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "41f1ebec-953a-4bb6-ae98-6579694792f2",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-05T15:55:10.363862Z",
     "iopub.status.busy": "2024-09-05T15:55:10.363249Z",
     "iopub.status.idle": "2024-09-05T16:01:52.370818Z",
     "shell.execute_reply": "2024-09-05T16:01:52.369340Z",
     "shell.execute_reply.started": "2024-09-05T15:55:10.363809Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'agent_outcome': AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"weather in San Francisco\"}', 'name': 'tavily_search_results_json'}}, response_metadata={'finish_reason': 'function_call', 'model_name': 'gpt-3.5-turbo-1106', 'system_fingerprint': 'fp_1867888df6'}, id='run-ba771577-5d06-46b6-a3e6-2639f32748ae-0')])}\n",
      "----\n",
      "{'intermediate_steps': [(AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"weather in San Francisco\"}', 'name': 'tavily_search_results_json'}}, response_metadata={'finish_reason': 'function_call', 'model_name': 'gpt-3.5-turbo-1106', 'system_fingerprint': 'fp_1867888df6'}, id='run-ba771577-5d06-46b6-a3e6-2639f32748ae-0')]), '[{\\'url\\': \\'https://www.weatherapi.com/\\', \\'content\\': \"{\\'location\\': {\\'name\\': \\'San Francisco\\', \\'region\\': \\'California\\', \\'country\\': \\'United States of America\\', \\'lat\\': 37.78, \\'lon\\': -122.42, \\'tz_id\\': \\'America/Los_Angeles\\', \\'localtime_epoch\\': 1725551591, \\'localtime\\': \\'2024-09-05 08:53\\'}, \\'current\\': {\\'last_updated_epoch\\': 1725551100, \\'last_updated\\': \\'2024-09-05 08:45\\', \\'temp_c\\': 15.1, \\'temp_f\\': 59.2, \\'is_day\\': 1, \\'condition\\': {\\'text\\': \\'Partly cloudy\\', \\'icon\\': \\'//cdn.weatherapi.com/weather/64x64/day/116.png\\', \\'code\\': 1003}, \\'wind_mph\\': 3.8, \\'wind_kph\\': 6.1, \\'wind_degree\\': 20, \\'wind_dir\\': \\'NNE\\', \\'pressure_mb\\': 1018.0, \\'pressure_in\\': 30.05, \\'precip_mm\\': 0.0, \\'precip_in\\': 0.0, \\'humidity\\': 100, \\'cloud\\': 25, \\'feelslike_c\\': 15.1, \\'feelslike_f\\': 59.2, \\'windchill_c\\': 16.5, \\'windchill_f\\': 61.7, \\'heatindex_c\\': 16.5, \\'heatindex_f\\': 61.7, \\'dewpoint_c\\': 12.9, \\'dewpoint_f\\': 55.3, \\'vis_km\\': 16.0, \\'vis_miles\\': 9.0, \\'uv\\': 5.0, \\'gust_mph\\': 4.2, \\'gust_kph\\': 6.7}}\"}]')]}\n",
      "----\n",
      "{'agent_outcome': AgentFinish(return_values={'output': 'The current weather in San Francisco is partly cloudy with a temperature of 59.2°F (15.1°C). The wind is blowing from the north-northeast at a speed of 6.1 kph. The humidity is at 100%, and the visibility is 9.0 miles.'}, log='The current weather in San Francisco is partly cloudy with a temperature of 59.2°F (15.1°C). The wind is blowing from the north-northeast at a speed of 6.1 kph. The humidity is at 100%, and the visibility is 9.0 miles.')}\n",
      "----\n"
     ]
    }
   ],
   "source": [
    "# todo, how to input the chat_history\n",
    "inputs = {\"input\": \"what is the weather in sf\", \n",
    "          \"chat_history\": []}\n",
    "for s in app.stream(inputs):\n",
    "    print(list(s.values())[0])\n",
    "    print(\"----\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4660642c-b1d8-4571-8be2-a9c6bbf9bae0",
   "metadata": {},
   "source": [
    "#### 管理 intermediate_steps"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "461e6e3d-bc63-4436-b926-02392b2cbc99",
   "metadata": {},
   "source": [
    "```\n",
    "# Define the agent\n",
    "def run_agent(state):\n",
    "    agent_outcome = agent_runnable.invoke(state)\n",
    "    return {\"agent_outcome\": agent_outcome}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bcac5869-85b9-4e8f-ab53-c398ef105d63",
   "metadata": {},
   "source": [
    "```\n",
    "# Define the agent\n",
    "def run_agent(state):\n",
    "    inputs = state.copy()\n",
    "    if len(inputs[\"intermediate_steps\"]) > 5:\n",
    "        inputs[\"intermediate_steps\"] = inputs[\"intermediate_steps\"][-5:]\n",
    "    agent_outcome = agent_runnable.invoke(inputs)\n",
    "    return {\"agent_outcome\": agent_outcome}\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a1edae58-1a9b-45b8-9b46-e3ee016ab45d",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "agent",
   "language": "python",
   "name": "agent"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
